;+
; NAME:
;       OMNI_MASS_SETUP
;
; PURPOSE:
;       Perform setup for mass computation -- code was duplicated in
;       various routines, so consolidated here.
;
; CATEGORY:
;       distance-omnibus Mass Subroutine
;
; CALLING SEQUENCE:
;       status = OMNI_MASS_SETUP( [CONFFILE=cfile] [,TYPSTR=typstr]
;                                 [,VERBOSE=verbose] [,SILENT=silent] )
;
; INPUTS:
;       NONE
;
; OPTIONAL INPUTS:
;       CONFFILE -- Name of the configuration file to use for survey
;                   information [Default: conffiles/survey_info.conf]
;       TYPSTR   -- String containing the type of computation that is
;                   being set up; used for terminal display only.
;                   [Default: 'UNKNOWN']
;
; KEYWORD PARAMETERS:
;       VERBOSE -- Cause the routine to contract logorrhoea.
;       SILENT  -- Mum's the word.
;
; OUTPUTS:
;       STATUS -- Did the routine run through to completion?
;
;
; OPTIONAL OUTPUTS:
;
;
;
; COMMON BLOCKS:
;       OMNI_CONFIG -- The set of configuration structures, read in
;                      from the config files in conffiles/
;       MASS_BLOCK  -- Set of variables read in and computed in
;                      OMNI_MASS_SETUP which are used in other
;                      mass-related routines.
;
; MODIFICATION HISTORY:
;
;       Created:  02/04/14, TPEB -- Initial version, with code lifted
;                                   from OMNI_MASS_FUNCTION.pro.
;
;-

FUNCTION OMNI_MASS_SETUP, CONFFILE=cfile, TYPSTR=typstr, $
                          VERBOSE=verbose, SILENT=silent
  
  COMPILE_OPT IDL2, LOGICAL_PREDICATE, HIDDEN
  
  COMMON OMNI_CONFIG, conf, mw, local, dpdfs, ancil, fmt, conffile
  COMMON MASS_BLOCK, pvec, s, iflux, ieflux, m0, hnuk, kappa, nkp
  
  ;; Parse keywords
  verbose  = KEYWORD_SET(verbose) && ~KEYWORD_SET(silent)
  silent   = KEYWORD_SET(silent)  && ~KEYWORD_SET(verbose)
  IF ~n_elements(typstr) THEN typstr = 'UNKNOWN'
  status = 0b
  
  ;; Read in survey-info, galactic-params, & dpdf-params config files
  conf     = omni_load_conf(cfile)
  mconf    = omni_read_conffile('./conffiles/mass_deriv.conf')
  
  ;; Read in the SURVEY catalog & PVEC structure -- IF PVEC does not
  ;;   exist, then spawn a warning and call DISTANCE_OMNIBUS.pro!
  s = omni_read_cat(conf.cat,ncat,fmt)
  pvfn = './local/'+conf.survey+'_pvec.sav'
  IF ~file_test(pvfn,/read) THEN BEGIN
     message,'The DPDF structure '+pvfn+' does not exist!  Running '+$
             'distance-omnibus to compute the DPDFs for '+conf.survey+'.',/inf
     distance_omnibus, CONFFILE=cfile
  ENDIF
  restore,pvfn,VERBOSE=verbose
  
  
  ;;=========================================================================
  ;; From mass-deriv config file, determine which DPDFs must be present
  need = bytarr(n_tags(mconf.need))
  FOR ll=0,n_tags(mconf.need)-1 DO need[ll] = mconf.need.(ll)
  iout = where(need,nout)
  tags = tag_names(constrain)
  IF nout THEN BEGIN
     ftags = (tag_names(mconf.need))[iout]
     
     ;; Winnow pvec structure to those requested for computation
     FOR ii=0,nout-1 DO BEGIN
        
        ;; Check that this tag exists in CONSTRAIN
        cind = where(tags EQ ftags[ii],nc)
        IF ~nc THEN BEGIN
           message,'Error: Requested DPDF constraint '+ftags[ii]+' for '+$
                   typstr+' computation (mass-deriv) has no '+$
                   'matches amongst source objects.  Exiting.',/cont
           RETURN, status
        ENDIF
        
        ;; Check that this tag has any sources attached
        keepi = where(constrain.(cind),nkp)
        IF ~nkp THEN BEGIN
           message,'Error: Requested DPDF constraint '+ftags[ii]+' for '+$
                   typstr+' computation (mass-deriv) has no '+$
                   'matches amongst source objects.  Exiting.',/cont
           RETURN, status
        ENDIF
        s         = s[keepi]
        pvec      = pvec[keepi]
        constrain = constrain[keepi]
        IF ~silent THEN $
           message,'For physical property computation, using '+ftags[ii]+$
                   ' constraint, kept '+strtrim(nkp,2)+' objects.',/inf
     ENDFOR
  ENDIF ELSE $
     IF ~silent THEN $
        message,'For '+typstr+' computation, no additional '+$
                'constraints beyond a kinematic distance are requested.',/inf
  
  
  
  ;;=========================================================================
  ;; Now that we have our set of sources with the proper DPDFs, we
  ;; need to further winnow to those with CONSTRAIN.POST = 1b
  keepi = where(constrain.post,nkp)
  IF ~nkp THEN BEGIN
     message,'Error: No sources with requested DPDFs have well-constrained '+$
             'distance estimates!  Exiting.',/cont
     RETURN, status
  ENDIF
  s         = s[keepi]
  pvec      = pvec[keepi]
  constrain = constrain[keepi]
  IF ~silent THEN $
     message,'For '+typstr+' computation, kept '+strtrim(nkp,2)+$
             ' objects with well-constrained distance estimates.',/inf
  
  
  ;;=========================================================================
  ;; Check that the INTEGRATED INTENSITY aperture (and associated
  ;;   error) are present in the catalog.
  IF ~TAG_EXIST(s,conf.s[0].val,INDEX=iflux) ||  $
     ~TAG_EXIST(s,conf.s[0].err,INDEX=ieflux) THEN BEGIN
     message,'Error: Tags specified in survey-info config file for '+$
             'integrated flux density aperture are not present in the '+$
             'catalog.  Exiting.',/cont
     RETURN, status
  ENDIF
  

  ;; Looks like we're in the clear!
  status = 1b
  
  ;;=========================================================================
  ;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  ;;=========================================================================
  ;; Onward with the physics!
  ;; Invoke the physical constant routine, with system variable !pc
  omni_physical_constants
  
  ;; Compute the fiducial mass as NNN.N M_sun *
  ;;  (e^(hv/kT)-1)/(e^(hv/k*T_ref)-1) * (D/1kpc)^2 * (S/1Jy)
  kappa = conf.kappa/10.d/mw.gas2dust ; dust opactiy       [m^2 kg^-1]
  hnuk = !pc.h*conf.nu/!pc.kb         ; h*nu/kb            [K]
  
  m0 = !pc.c*!pc.c*!pc.Jy*(exp(hnuk/mw.td)-1.d) * !pc.kpc*!pc.kpc / $
       (2.d*!pc.h*conf.nu*conf.nu*conf.nu*kappa*!pc.msun)
  
  IF ~silent THEN BEGIN
     print,''
     message,'Fiducial mass for '+conf.survey+' is '+$
             string(m0,format="(F0.1)")+' M_sun for a 1 Jy object at 1 kpc, '+$
             'assuming Td = '+string(mw.td,format="(I0)")+'K and a gas:dust '+$
             'ratio of '+string(mw.gas2dust,format="(I0)")+'.',/inf
     print,''
  ENDIF
  
  RETURN,status
END
